﻿using System;
using System.Windows.Browser;

namespace SilverCrmSoap.Helpers
{
    /// <summary>
    /// XrmHelper: A static class to assist in accessing the JScript Xrm Objects and the Xrm Context
    /// </summary>
    public static class XrmHelper
    {
        private static ScriptObject _xrm;

        private static ScriptObject _xrmPage;

        private static ScriptObject _context;

        private static ScriptObject _xrmPageData;

        private static ScriptObject _xrmPageDataEntity;

        private static ScriptObject _xrmPageDataEntityAttributes;

        private static Uri _serverUrl;

        /// <summary>
        /// OnForm: A boolean to detect whether or not a Silverlight Application was loaded on a form
        /// </summary>
        public static bool OnForm { 
            get
            {
                return (Xrm != null);
            }
        }

        /// <summary>
        /// Xrm: Access to the JScript Object Xrm
        /// </summary>
        public static ScriptObject Xrm
        {
            get { return _xrm ?? (_xrm = (ScriptObject) HtmlPage.Window.GetProperty("Xrm")); }
        }

        /// <summary>
        /// XrmPage: Access to the JScript Object Xrm.Page
        /// </summary>
        public static ScriptObject XrmPage
        {
            get { return _xrmPage ?? (_xrmPage = Xrm==null ? null : (ScriptObject) Xrm.GetProperty("Page")); }
        }

        /// <summary>
        /// Context: The Global Context or Xrm.Page.context
        /// </summary>
        public static ScriptObject Context
        {
            get
            {
                if (_context != null) return _context;
                _context = (ScriptObject) XrmPage.GetProperty("context");
                if (_context != null) return _context;
                _context = (ScriptObject)HtmlPage.Window.Invoke("GetGlobalContext");
                return _context;
            }
        }

        /// <summary>
        /// XrmPageData: Access to the JScript Object Xrm.Page.data
        /// </summary>
        public static ScriptObject XrmPageData
        {
            get { return _xrmPageData ?? (_xrmPageData = XrmPage==null ? null : (ScriptObject) XrmPage.GetProperty("data")); }
        }

        /// <summary>
        /// XrmPageDataEntityAttributes: Access to the JScript Object Xrm.Page.data.entity.attributes
        /// </summary>
        public static ScriptObject XrmPageDataEntity
        {
            get { return _xrmPageDataEntity ?? (_xrmPageDataEntity = XrmPageData==null ? null : (ScriptObject) XrmPageData.GetProperty("entity")); }
        }

        /// <summary>
        /// XrmPageDataEntityAttributes: Access to the JScript Object Xrm.Page.data.entity.attributes
        /// </summary>
        public static ScriptObject XrmPageDataEntityAttributes
        {
            get
            {
                return _xrmPageDataEntityAttributes ??
                    (_xrmPageDataEntityAttributes = XrmPageDataEntity==null ? null : (ScriptObject) XrmPageDataEntity.GetProperty("attributes"));
            }
        }

        /// <summary>
        /// ServerUri: The Server Uri
        /// </summary>
        public static Uri ServerUri
        {
            get { return _serverUrl ?? (_serverUrl = GetServerUri()); }
        }

        #region Private Methods

        /// <summary>
        /// GetServerUrl: Get the Server Url using the context
        /// </summary>
        /// <returns></returns>
        private static Uri GetServerUri()
        {
            var serverUrl = (string) Context.Invoke("getServerUrl");
            // Remove the trailing forwards slash returned by CRM Online
            // So that it is always consistent with CRM On Premises
            int end = serverUrl.Length - 1;
            if (serverUrl[end] == '/') serverUrl = serverUrl.Substring(0, end);

            return new Uri(serverUrl);
        }
 
        #endregion
    }
}